package com.hmall.order.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.hmall.feign.client.ItemClient;
import com.hmall.feign.client.UserClient;
import com.hmall.item.pojo.Item;
import com.hmall.order.dto.OrderDto;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.service.OrderService;
import com.hmall.utils.WXPayUtil;
import com.hmall.winxin.WXConstants;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import io.seata.spring.annotation.GlobalTransactional;

import javax.servlet.ServletInputStream;
import java.util.*;

@Slf4j
@Service
public class OrderServiceimpl implements OrderService {
    @Autowired
    ItemClient itemClient;
    @Autowired
    UserClient userClient;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    ItemClient itemClientl;
    @Override
    public Order inserOrder(OrderDto orderDto) {
        Order order=new Order();
        order.setPaymentType(orderDto.getPaymentType());
        Item item=itemClient.queryItemById(orderDto.getItemId());
        order.setTotalFee(item.getPrice()*orderDto.getNum());
        Long addressid=orderDto.getAddressId();
        order.setUserId(userClient.findAddressById(addressid,"6").getUserId());

        order.setCreateTime(new Date());
        order.setStatus(0);
        orderMapper.insert(order);
        return orderMapper.selectLast();

    }

    @Override
    @GlobalTransactional
    public void updateStock(OrderDto orderDto) {
        itemClientl.updateStock(orderDto.getItemId(), orderDto.getNum());
    }

    @Override
    public Order queryById(Long id) {
        return orderMapper.selectById(id);
    }
@Autowired
OrderDetailMapper orderDetailMapper;
    @Override
    public String orderPay(Integer type, Long orderId) throws Exception {
        OrderDetail orderDetail = orderDetailMapper.selectOne(Wrappers.<OrderDetail>query().eq("order_id", orderId));

        //以map集合的形式，封装微信支付的请求参数
        Map<String, String> map = Maps.newHashMap();
        map.put("appid", WXConstants.APP_ID); //公众账号ID
        map.put("mch_id", WXConstants.MCH_ID);//商户号
        map.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
        map.put("body", orderDetail.getName());//商品描述
        map.put("out_trade_no", String.valueOf(orderId));//商户订单号
        map.put("total_fee", "1");//标价金额
        map.put("spbill_create_ip", "127.0.0.1");//终端IP
        map.put("notify_url", WXConstants.NOTIFY_URL);//通知地址
        map.put("trade_type", "NATIVE");//Native支付
        //将map集合转成xml格式，并且生成参数的签名
        String xml = WXPayUtil.generateSignedXml(map);

        //和微信支付对接，获取支付二维码地址
        HttpResponse response = HttpUtil.createPost(WXConstants.API_URL) //POST请求
                .body(xml) //请求体的数据
                .header("Content-Type", "application/xml")//请求体：表述的是请求体的数据格式为xml类型
                .execute();//发送请求

        String xmlBody = response.body(); //xml

        //将xml格式转为map集合
        map = WXPayUtil.xmlToMap(xmlBody);

        //判断微信返回的数据是否是SUCCESS
        if (StrUtil.endWithIgnoreCase("SUCCESS", map.get("return_code"))) {
            //响应正常
            return map.get("code_url");
        } else {
            //有异常
            throw new RuntimeException(map.get("return_msg"));
        }
    }
    @SneakyThrows
    @Override
    public Map<String, String> payNotify(ServletInputStream inputStream) {
        String xml = WXPayUtil.convertToString(inputStream);
        Map<String, String> result = new HashMap<>();
        //解析
        Map<String, String> map = WXPayUtil.xmlToMap(xml);        //验签

        boolean signatureValid = WXPayUtil.isSignatureValid(map);

        if (signatureValid) {
            if ("SUCCESS".equals(map.get("result_code"))) {
                result.put("return_code", "SUCCESS");//成功
                result.put("return_msg", "OK");//订单号
                String out_trade_no = map.get("out_trade_no");
                Order order = orderMapper.selectById(out_trade_no);
                order.setStatus(2); //已付款
                order.setPayTime(new Date());
                orderMapper.updateById(order);
                return result;
            } else {
                log.info("支付回调出错:" + xml);
                result.put("return_code", "FAIL");//失败
                return result;
            }
        } else {
            log.info("支付回调验签失败:" + xml);
            result.put("return_code", "FAIL");//失败
            return result;
        }
    }


    public void ordertime(Date date) {

    }
}
